package com.quiltplayer.internal.id3.impl;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioSystem;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.tritonus.share.sampled.file.TAudioFileFormat;
import com.quiltplayer.internal.id3.Id3Extractor;
import com.quiltplayer.internal.id3.model.DataStorage;
import com.quiltplayer.internal.id3.model.Id3DataModel;
/**
* General ID3 extractor using mp3spi.jar. Error handling is limited but the general idea is that the
* failed files should be published in the application.
*
* @author Vlado Palczynski
*/
@Component
public class Mp3SpiId3Extractor implements Id3Extractor {
private Pattern p = Pattern.compile("^[0-9]+");
private DataStorage storage;
/*
* (non-Javadoc)
*
* @see com.quiltplayer.id3utils.Id3Extractor#extractFile(java.io.File)
*/
public void extractId3Tags(Collection<File> files, DataStorage storage) {
this.storage = storage;
int i = 0;
for (File file : files) {
extract(file);
storage.progress(++i);
}
}
/*
* (non-Javadoc)
*
* @see com.quiltplayer.id3utils.Id3Extractor#extractByAlbum(java.util.List)
*/
public Collection<Id3DataModel> extractId3Tags(Collection<File> files) {
List<Id3DataModel> l = new ArrayList<Id3DataModel>();
for (File file : files) {
extract(file);
}
return l;
}
/**
* Storage for unsuccessful entries.
*/
private List<File> unsuccessfull = new ArrayList<File>();
/**
* Logger.
*/
private static Logger log = Logger.getLogger(Mp3SpiId3Extractor.class);
/**
* @param file
* the file to extract from.
* @return Id3DataModel
*/
private void extract(final File file) {
String albumTitle = null;
String artistName = null;
String songTitle = null;
String trackNumber = null;
Long duration = null;
// Extract information from ID3-tag
try {
AudioFileFormat baseFileFormat = AudioSystem.getAudioFileFormat(file);
if (baseFileFormat instanceof TAudioFileFormat) {
Map<String, ?> properties = ((TAudioFileFormat) baseFileFormat).properties();
albumTitle = (String) properties.get("album");
songTitle = (String) properties.get("title");
artistName = (String) properties.get("author");
trackNumber = (String) properties.get("mp3.id3tag.track");
duration = (Long) properties.get("duration");
}
Id3DataModel model = new Id3DataModel();
model.setAlbumTitle(albumTitle);
model.setArtistName(artistName);
model.setSongTitle(songTitle);
if (trackNumber != null) {
String fileName = file.getName();
Matcher m = p.matcher(fileName);
boolean b = false;
while (m.find()) {
model.setTrackNumber(Integer.parseInt(m.group()));
b = true;
log.debug("Setting song number to " + m.group());
}
if (!b)
model.setTrackNumber(Integer.parseInt(trackNumber));
}
else {
/* No good, check the file name if it starts with a number */
String fileName = file.getName();
Matcher m = p.matcher(fileName);
while (m.find()) {
model.setTrackNumber(Integer.parseInt(m.group()));
log.debug("Setting song number to " + m.group());
}
}
model.setPath(file.getAbsoluteFile());
model.setDuration(duration.intValue());
if (storage != null) {
storage.store(model);
}
}
catch (Exception e) {
unsuccessfull.add(file);
log.error(e.getMessage());
e.printStackTrace();
}
}
}